home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / sendmail / sendmail-5.65 / src / err.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-06-05  |  7.8 KB  |  380 lines

  1. /*
  2.  * Copyright (c) 1983 Eric P. Allman
  3.  * Copyright (c) 1988 Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms are permitted provided
  7.  * that: (1) source distributions retain this entire copyright notice and
  8.  * comment, and (2) distributions including binaries display the following
  9.  * acknowledgement:  ``This product includes software developed by the
  10.  * University of California, Berkeley and its contributors'' in the
  11.  * documentation or other materials provided with the distribution and in
  12.  * all advertising materials mentioning features or use of this software.
  13.  * Neither the name of the University nor the names of its contributors may
  14.  * be used to endorse or promote products derived from this software without
  15.  * specific prior written permission.
  16.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  17.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  18.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  19.  */
  20.  
  21. #ifndef lint
  22. static char sccsid[] = "@(#)err.c    5.10 (Berkeley) 6/1/90";
  23. #endif /* not lint */
  24.  
  25. # include "sendmail.h"
  26. # include <errno.h>
  27. # include <netdb.h>
  28.  
  29. /*
  30. **  SYSERR -- Print error message.
  31. **
  32. **    Prints an error message via printf to the diagnostic
  33. **    output.  If LOG is defined, it logs it also.
  34. **
  35. **    Parameters:
  36. **        f -- the format string
  37. **        a, b, c, d, e -- parameters
  38. **
  39. **    Returns:
  40. **        none
  41. **        Through TopFrame if QuickAbort is set.
  42. **
  43. **    Side Effects:
  44. **        increments Errors.
  45. **        sets ExitStat.
  46. */
  47.  
  48. # ifdef lint
  49. int    sys_nerr;
  50. char    *sys_errlist[];
  51. # endif lint
  52. char    MsgBuf[BUFSIZ*2];    /* text of most recent message */
  53.  
  54. /*VARARGS1*/
  55. syserr(fmt, a, b, c, d, e)
  56.     char *fmt;
  57. {
  58.     register char *p;
  59.     int olderrno = errno;
  60.     extern char Arpa_PSyserr[];
  61.     extern char Arpa_TSyserr[];
  62.  
  63.     /* format and output the error message */
  64.     if (olderrno == 0)
  65.         p = Arpa_PSyserr;
  66.     else
  67.         p = Arpa_TSyserr;
  68.     fmtmsg(MsgBuf, (char *) NULL, p, olderrno, fmt, a, b, c, d, e);
  69.     puterrmsg(MsgBuf);
  70.  
  71.     /* determine exit status if not already set */
  72.     if (ExitStat == EX_OK)
  73.     {
  74.         if (olderrno == 0)
  75.             ExitStat = EX_SOFTWARE;
  76.         else
  77.             ExitStat = EX_OSERR;
  78.     }
  79.  
  80. # ifdef LOG
  81.     if (LogLevel > 0)
  82.         syslog(LOG_CRIT, "%s: SYSERR: %s",
  83.             CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id,
  84.             &MsgBuf[4]);
  85. # endif LOG
  86.     errno = 0;
  87.     if (QuickAbort)
  88.         longjmp(TopFrame, 2);
  89. }
  90. /*
  91. **  USRERR -- Signal user error.
  92. **
  93. **    This is much like syserr except it is for user errors.
  94. **
  95. **    Parameters:
  96. **        fmt, a, b, c, d -- printf strings
  97. **
  98. **    Returns:
  99. **        none
  100. **        Through TopFrame if QuickAbort is set.
  101. **
  102. **    Side Effects:
  103. **        increments Errors.
  104. */
  105.  
  106. /*VARARGS1*/
  107. usrerr(fmt, a, b, c, d, e)
  108.     char *fmt;
  109. {
  110.     extern char SuprErrs;
  111.     extern char Arpa_Usrerr[];
  112.     extern int errno;
  113.  
  114.     if (SuprErrs)
  115.         return;
  116.  
  117.     fmtmsg(MsgBuf, CurEnv->e_to, Arpa_Usrerr, errno, fmt, a, b, c, d, e);
  118.     puterrmsg(MsgBuf);
  119.  
  120.     if (QuickAbort)
  121.         longjmp(TopFrame, 1);
  122. }
  123. /*
  124. **  MESSAGE -- print message (not necessarily an error)
  125. **
  126. **    Parameters:
  127. **        num -- the default ARPANET error number (in ascii)
  128. **        msg -- the message (printf fmt) -- if it begins
  129. **            with a digit, this number overrides num.
  130. **        a, b, c, d, e -- printf arguments
  131. **
  132. **    Returns:
  133. **        none
  134. **
  135. **    Side Effects:
  136. **        none.
  137. */
  138.  
  139. /*VARARGS2*/
  140. message(num, msg, a, b, c, d, e)
  141.     register char *num;
  142.     register char *msg;
  143. {
  144.     errno = 0;
  145.     fmtmsg(MsgBuf, CurEnv->e_to, num, 0, msg, a, b, c, d, e);
  146.     putmsg(MsgBuf, FALSE);
  147. }
  148. /*
  149. **  NMESSAGE -- print message (not necessarily an error)
  150. **
  151. **    Just like "message" except it never puts the to... tag on.
  152. **
  153. **    Parameters:
  154. **        num -- the default ARPANET error number (in ascii)
  155. **        msg -- the message (printf fmt) -- if it begins
  156. **            with three digits, this number overrides num.
  157. **        a, b, c, d, e -- printf arguments
  158. **
  159. **    Returns:
  160. **        none
  161. **
  162. **    Side Effects:
  163. **        none.
  164. */
  165.  
  166. /*VARARGS2*/
  167. nmessage(num, msg, a, b, c, d, e)
  168.     register char *num;
  169.     register char *msg;
  170. {
  171.     errno = 0;
  172.     fmtmsg(MsgBuf, (char *) NULL, num, 0, msg, a, b, c, d, e);
  173.     putmsg(MsgBuf, FALSE);
  174. }
  175. /*
  176. **  PUTMSG -- output error message to transcript and channel
  177. **
  178. **    Parameters:
  179. **        msg -- message to output (in SMTP format).
  180. **        holdmsg -- if TRUE, don't output a copy of the message to
  181. **            our output channel.
  182. **
  183. **    Returns:
  184. **        none.
  185. **
  186. **    Side Effects:
  187. **        Outputs msg to the transcript.
  188. **        If appropriate, outputs it to the channel.
  189. **        Deletes SMTP reply code number as appropriate.
  190. */
  191.  
  192. putmsg(msg, holdmsg)
  193.     char *msg;
  194.     bool holdmsg;
  195. {
  196.     /* output to transcript if serious */
  197.     if (CurEnv->e_xfp != NULL && (msg[0] == '4' || msg[0] == '5'))
  198.         fprintf(CurEnv->e_xfp, "%s\n", msg);
  199.  
  200.     /* output to channel if appropriate */
  201.     if (!holdmsg && (Verbose || msg[0] != '0'))
  202.     {
  203.         (void) fflush(stdout);
  204.         if (OpMode == MD_SMTP || OpMode == MD_ARPAFTP)
  205.             fprintf(OutChannel, "%s\r\n", msg);
  206.         else
  207.             fprintf(OutChannel, "%s\n", &msg[4]);
  208.         (void) fflush(OutChannel);
  209.     }
  210. }
  211. /*
  212. **  PUTERRMSG -- like putmsg, but does special processing for error messages
  213. **
  214. **    Parameters:
  215. **        msg -- the message to output.
  216. **
  217. **    Returns:
  218. **        none.
  219. **
  220. **    Side Effects:
  221. **        Sets the fatal error bit in the envelope as appropriate.
  222. */
  223.  
  224. puterrmsg(msg)
  225.     char *msg;
  226. {
  227.     /* output the message as usual */
  228.     putmsg(msg, HoldErrs);
  229.  
  230.     /* signal the error */
  231.     Errors++;
  232.     if (msg[0] == '5')
  233.         CurEnv->e_flags |= EF_FATALERRS;
  234. }
  235. /*
  236. **  FMTMSG -- format a message into buffer.
  237. **
  238. **    Parameters:
  239. **        eb -- error buffer to get result.
  240. **        to -- the recipient tag for this message.
  241. **        num -- arpanet error number.
  242. **        en -- the error number to display.
  243. **        fmt -- format of string.
  244. **        a, b, c, d, e -- arguments.
  245. **
  246. **    Returns:
  247. **        none.
  248. **
  249. **    Side Effects:
  250. **        none.
  251. */
  252.  
  253. /*VARARGS5*/
  254. static
  255. fmtmsg(eb, to, num, eno, fmt, a, b, c, d, e)
  256.     register char *eb;
  257.     char *to;
  258.     char *num;
  259.     int eno;
  260.     char *fmt;
  261. {
  262.     char del;
  263.  
  264.     /* output the reply code */
  265.     if (isdigit(fmt[0]) && isdigit(fmt[1]) && isdigit(fmt[2]))
  266.     {
  267.         num = fmt;
  268.         fmt += 4;
  269.     }
  270.     if (num[3] == '-')
  271.         del = '-';
  272.     else
  273.         del = ' ';
  274.     (void) sprintf(eb, "%3.3s%c", num, del);
  275.     eb += 4;
  276.  
  277.     /* output the file name and line number */
  278.     if (FileName != NULL)
  279.     {
  280.         (void) sprintf(eb, "%s: line %d: ", FileName, LineNumber);
  281.         eb += strlen(eb);
  282.     }
  283.  
  284.     /* output the "to" person */
  285.     if (to != NULL && to[0] != '\0')
  286.     {
  287.         (void) sprintf(eb, "%s... ", to);
  288.         while (*eb != '\0')
  289.             *eb++ &= 0177;
  290.     }
  291.  
  292.     /* output the message */
  293.     (void) sprintf(eb, fmt, a, b, c, d, e);
  294.     while (*eb != '\0')
  295.         *eb++ &= 0177;
  296.  
  297.     /* output the error code, if any */
  298.     if (eno != 0)
  299.     {
  300.         extern char *errstring();
  301.  
  302.         (void) sprintf(eb, ": %s", errstring(eno));
  303.         eb += strlen(eb);
  304.     }
  305. }
  306. /*
  307. **  ERRSTRING -- return string description of error code
  308. **
  309. **    Parameters:
  310. **        errno -- the error number to translate
  311. **
  312. **    Returns:
  313. **        A string description of errno.
  314. **
  315. **    Side Effects:
  316. **        none.
  317. */
  318.  
  319. char *
  320. errstring(errno)
  321.     int errno;
  322. {
  323.     extern char *sys_errlist[];
  324.     extern int sys_nerr;
  325.     static char buf[100];
  326. # ifdef SMTP
  327.     extern char *SmtpPhase;
  328. # endif SMTP
  329.  
  330. # ifdef DAEMON
  331. # ifdef VMUNIX
  332.     /*
  333.     **  Handle special network error codes.
  334.     **
  335.     **    These are 4.2/4.3bsd specific; they should be in daemon.c.
  336.     */
  337.  
  338.     switch (errno)
  339.     {
  340.       case ETIMEDOUT:
  341.       case ECONNRESET:
  342.         (void) strcpy(buf, sys_errlist[errno]);
  343.         if (SmtpPhase != NULL)
  344.         {
  345.             (void) strcat(buf, " during ");
  346.             (void) strcat(buf, SmtpPhase);
  347.         }
  348.         if (CurHostName != NULL)
  349.         {
  350.             (void) strcat(buf, " with ");
  351.             (void) strcat(buf, CurHostName);
  352.         }
  353.         return (buf);
  354.  
  355.       case EHOSTDOWN:
  356.         if (CurHostName == NULL)
  357.             break;
  358.         (void) sprintf(buf, "Host %s is down", CurHostName);
  359.         return (buf);
  360.  
  361.       case ECONNREFUSED:
  362.         if (CurHostName == NULL)
  363.             break;
  364.         (void) sprintf(buf, "Connection refused by %s", CurHostName);
  365.         return (buf);
  366.  
  367.       case (TRY_AGAIN+MAX_ERRNO):
  368.         (void) sprintf(buf, "Host Name Lookup Failure");
  369.         return (buf);
  370.     }
  371. # endif VMUNIX
  372. # endif DAEMON
  373.  
  374.     if (errno > 0 && errno < sys_nerr)
  375.         return (sys_errlist[errno]);
  376.  
  377.     (void) sprintf(buf, "Error %d", errno);
  378.     return (buf);
  379. }
  380.